#include<bits/stdc++.h>
using namespace std;
#define int long long
int T;
int n,m,L,V;
int d[100010],v[100010],a[100010],p[100010],vis[100010];
struct node{
    int l,r;
    bool operator<(const node &b)const{
        return r<b.r;
    }
}b[100010];
bool check(int id,int x){
    int s=p[id]-d[x];
    int v_max=v[x]*v[x]+2*a[x]*s;
    if(v_max>V*V&&v_max>=0) return 1;
    return 0;
}
void solve(){
    scanf("%lld%lld%lld%lld",&n,&m,&L,&V);
    for(int i=1;i<=n;i++) scanf("%lld%lld%lld",&d[i],&v[i],&a[i]),vis[i]=0;
    for(int i=1;i<=m;i++) scanf("%lld",&p[i]);
    int ans=0;
    for(int i=1;i<=n;i++){
        if(d[i]>p[m]) continue;
        if(a[i]>=0){
            int s=p[m]-d[i];
            int v_max=v[i]*v[i]+2*a[i]*s;
            if(v_max>V*V) ans++,vis[i]=1;
        }else{
            int id=lower_bound(p+1,p+m+1,d[i])-p;
            int s=p[id]-d[i];
            int v_max=v[i]*v[i]+2*a[i]*s;
            if(v_max>V*V) ans++,vis[i]=1;
        }
    }
    printf("%lld ",ans);
    int cnt=0;
    for(int i=1;i<=n;i++){
        if(!vis[i]) continue;
        if(a[i]>=0){
            int s;
            if(v[i]>V) s=0;
            else s=(V*V-v[i]*v[i])/(2*a[i])+1;
            s+=d[i];
            int l=lower_bound(p+1,p+m+1,s)-p;
            int r=m;
            b[++cnt].l=l,b[cnt].r=r;
        }else{
            int l=lower_bound(p+1,p+m+1,d[i])-p,r=m;
            int R=l;
            while(l<=r){
                int mid=(l+r)>>1;
                if(check(mid,i)) l=mid+1,R=mid;
                else r=mid-1;
            }
            l=lower_bound(p+1,p+m+1,d[i])-p;
            b[++cnt].l=l,b[cnt].r=R;
        }
    }
    sort(b+1,b+cnt+1);
    int st=-1;
    ans=0;
    for(int i=1;i<=cnt;i++) if(b[i].l>st) st=b[i].r,ans++;
    printf("%lld",m-ans);
    printf("\n");
}
signed main(){
    freopen("detect.in","r",stdin);
    freopen("detect.out","w",stdout);
    scanf("%lld",&T);
    while(T--) solve();
    return 0;
}
